using System;
using System.Xml.Serialization;

namespace ElfBinary
{
	[Serializable]
	public class SymbolTableEntry64
	{

		public SymbolTableEntry64()
		{
		}

		public ulong Size { get { return st_size; }}

		[XmlIgnore]
		public SectionHeader64 Parent {get;set;}

		public SectionHeader64 StringTable {get;set;}



		int btype = -1;

		[XmlElement]
		public ElfSymbolBinding BindType 
		{
			 get 
			{ 

				if (btype > -1) { 
					return (ElfSymbolBinding) (byte)btype;
				}
				return (ElfSymbolBinding)((byte)(st_info >> 4)); 
			}

			set {

				btype = (byte)value;
			
				}
		}


		int stype =-1;

		[XmlElement]
		public ElfSymbolType SymbolType 
			{
				 get
					 { 

				if (stype > -1)
					return (ElfSymbolType)((byte) stype);

				return (ElfSymbolType)  ((byte)(st_info &  0xf)); 
			}

			set {
				stype = (byte) value;
			}
		}


		private string _name = null;

		[XmlElement]
		public string SymbolName
		{
			get {

				if (_name != null)
					return _name;
			
				return	Parent.Parent.SectionHeaders64
					[(int)Parent.Link].GetString (st_name);
			}

			set {
				_name = value;
			}
		}

		[XmlElement]
		public ElfSymbolVisibility Visibility
		{
			get {
				return  (ElfSymbolVisibility)
					((byte)st_other & 0x3);
					}
			set {
				st_other = (byte)value;
			}
		}

		[XmlElement]
		public ushort SectionHeaderIndex
		{
			get { return st_shndx; }
			set { st_shndx = value; }
		}

		[XmlElement]
		public ulong Value
		{
			get { return st_value; }
			set { st_value = Value; }
		}

		public SymbolTableEntry64 (SectionHeader64 parent)
		{
			Parent = parent;
		}

		public int Read (byte[] buffer, int offset)
		{
			int index = offset;

			st_name = BitConverter.ToUInt32 (buffer, index);
			index += 4;
			st_info = buffer [index];
			index++;
			st_other = buffer [index];
			index++;
			st_shndx = BitConverter.ToUInt16 (buffer, index);
			index += 2;
			st_value = BitConverter.ToUInt64 (buffer, index);
			index += 8;
			st_size = BitConverter.ToUInt64 (buffer, index);
			index += 8;

			return index;
		}

		private uint	st_name;
		private	byte	st_info;
		private byte	st_other;
		private ushort	st_shndx;
		private ulong	st_value;
		private ulong	st_size;

	}
}

